const QuestionComment = require('../models/QuestionComment.js')
const CommentLike = require('../models/CommentLike.js')
const User = require('../models/User.js')
const Question = require('../models/Question.js')
const { Op } = require('sequelize');
const sequelize = require('../db/db');
const { sendResponse, sendListResponse } = require('../utils/response');
const { getTimestamp, getTwoDigits, formatObject, formatTime } = require('../utils/common');

/**
 * 添加题目评论
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const addQuestionComment = async (req, res) => {
  try {
    const { userId, questionId, content, difficultyRating, qualityRating } = req.body;

    // 参数验证
    if (!questionId || !content) {
      return sendResponse(res, 500, '参数错误: 题目ID和评论内容不能为空');
    }

    // 验证题目是否存在
    const question = await Question.findByPk(questionId);
    if (!question) {
      return sendResponse(res, 500, '题目不存在');
    }

    // 生成评论ID
    const commentId = "192" + getTimestamp() + getTwoDigits();

    // 处理评分，确保只保留1位小数
    const formattedDifficultyRating = difficultyRating ? difficultyRating : null;
    const formattedQualityRating = qualityRating ? qualityRating : null;

    // 创建评论记录
    const comment = await QuestionComment.create({
      id: commentId,
      question_id: questionId,
      user_id: userId,
      content,
      difficulty_rating: formattedDifficultyRating,
      quality_rating: formattedQualityRating,
      likes: 0,
      create_time: formatTime(new Date())
    });

    // 如果提供了评分，更新题目的平均评分
    if (formattedDifficultyRating || formattedQualityRating) {
      await updateQuestionAverageRatings(questionId);
    }

    // 返回创建的评论
    const createdComment = await QuestionComment.findByPk(commentId, {
      include: [{
        model: User,
        as: 'user',
        attributes: ['user_id', 'nickname']
      }]
    });

    sendResponse(res, 200, '评论发表成功', formatObject({
      id: createdComment.id,
      content: createdComment.content,
      difficultyRating: createdComment.difficulty_rating,
      qualityRating: createdComment.quality_rating,
      likes: createdComment.likes,
      createTime: createdComment.create_time,
      user: {
        userId: createdComment.user.user_id,
        nickname: createdComment.user.nickname
      }
    }));
  } catch (error) {
    console.error('发表评论失败:', error);
    sendResponse(res, 500, '发表评论失败', error.message);
  }
};

/**
 * 获取题目评论列表
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getQuestionComments = async (req, res) => {
  try {
    const { questionId, page = 1, pageSize = 10, sortBy = '1' } = req.query;

    // 参数验证
    if (!questionId) {
      return sendResponse(res, 500, '参数错误: 题目ID不能为空');
    }

    // 计算偏移量
    const offset = (parseInt(page) - 1) * parseInt(pageSize);

    // 确定排序
    let order = [];
    if (sortBy === '1') {
      order = [['likes', 'DESC']];
    } else if (sortBy === '2') {
      order = [['create_time', 'DESC']];
    }

    // 查询评论及其关联用户
    const { count, rows } = await QuestionComment.findAndCountAll({
      where: {
        question_id: questionId
      },
      include: [
        {
          model: User,
          as: 'user',
          attributes: ['user_id', 'nickname']
        }
      ],
      order,
      limit: parseInt(pageSize),
      offset: parseInt(offset)
    });

    // 格式化评论数据
    const formattedComments = await Promise.all(rows.map(async (comment) => {
      const commentData = comment.toJSON();

      // 默认未点赞
      let isLiked = false;

      // 如果用户已登录，检查是否已点赞
      if (req.user) {
        const likeRecord = await CommentLike.findOne({
          where: {
            comment_id: comment.id,
            user_id: req.user.userId
          }
        });
        isLiked = !!likeRecord;
      }

      return formatObject({
        id: commentData.id,
        content: commentData.content,
        difficultyRating: commentData.difficulty_rating,
        qualityRating: commentData.quality_rating,
        likes: commentData.likes,
        createTime: commentData.create_time,
        isLiked,
        user: {
          userId: commentData.user.user_id,
          nickname: commentData.user.nickname
        }
      });
    }));

    // 返回评论列表
    sendListResponse(res, 200, '获取评论成功', formattedComments, count);
  } catch (error) {
    console.error('获取题目评论失败:', error);
    sendResponse(res, 500, '获取题目评论失败', error.message);
  }
};

/**
 * 点赞/取消点赞评论
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const likeComment = async (req, res) => {
  try {
    const { userId, commentId } = req.body;

    // 参数验证
    if (!commentId) {
      return sendResponse(res, 500, '参数错误: 评论ID不能为空');
    }

    // 验证评论是否存在
    const comment = await QuestionComment.findByPk(commentId);
    if (!comment) {
      return sendResponse(res, 500, '评论不存在');
    }

    // 使用事务确保数据一致性
    const transaction = await sequelize.transaction();

    try {
      // 检查是否已点赞
      const existingLike = await CommentLike.findOne({
        where: {
          comment_id: commentId,
          user_id: userId
        },
        transaction
      });

      if (existingLike) {
        // 如果已点赞，则取消点赞
        await existingLike.destroy({ transaction });

        // 减少评论点赞数
        await comment.decrement('likes', { transaction });

        await transaction.commit();
        sendResponse(res, 200, '取消点赞成功');
      } else {
        // 如果未点赞，则添加点赞
        const likeId = "193" + getTimestamp() + getTwoDigits();

        await CommentLike.create({
          id: likeId,
          comment_id: commentId,
          user_id: userId,
          create_time: formatTime(new Date())
        }, { transaction });

        // 增加评论点赞数
        await comment.increment('likes', { transaction });

        await transaction.commit();
        sendResponse(res, 200, '点赞成功');
      }
    } catch (error) {
      // 如果出错，回滚事务
      await transaction.rollback();
      throw error;
    }
  } catch (error) {
    console.error('评论点赞操作失败:', error);
    sendResponse(res, 500, '评论点赞操作失败', error.message);
  }
};

/**
 * 更新评论
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const updateComment = async (req, res) => {
  try {
    const { id, userId, content, difficultyRating, qualityRating } = req.body;

    // 查找评论
    const comment = await QuestionComment.findByPk(id);
    if (!comment) {
      return sendResponse(res, 500, '评论不存在');
    }

    // 验证操作权限（只有评论作者可以更新）
    if (comment.user_id !== userId) {
      return sendResponse(res, 500, '无权修改此评论');
    }

    // 准备更新数据
    const updateData = {
      update_time: formatTime(new Date())
    };

    if (content) {
      updateData.content = content;
    }

    if (difficultyRating) {
      updateData.difficulty_rating = difficultyRating;
    }

    if (qualityRating) {
      updateData.quality_rating = qualityRating;
    }

    // 使用事务更新评论
    const transaction = await sequelize.transaction();

    try {
      // 更新评论
      await comment.update(updateData, { transaction });

      // 如果更新了评分，更新题目的平均评分
      if (difficultyRating !== undefined || qualityRating !== undefined) {
        await updateQuestionAverageRatings(comment.question_id, transaction);
      }

      await transaction.commit();

      // 获取更新后的评论
      const updatedComment = await QuestionComment.findByPk(id, {
        include: [{
          model: User,
          as: 'user',
          attributes: ['user_id', 'nickname']
        }]
      });

      sendResponse(res, 200, '评论更新成功', formatObject({
        id: updatedComment.id,
        content: updatedComment.content,
        difficultyRating: updatedComment.difficulty_rating,
        qualityRating: updatedComment.quality_rating,
        likes: updatedComment.likes,
        createTime: updatedComment.create_time,
        updateTime: updatedComment.update_time,
        user: {
          userId: updatedComment.user.user_id,
          nickname: updatedComment.user.nickname
        }
      }));
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  } catch (error) {
    console.error('更新评论失败:', error);
    sendResponse(res, 500, '更新评论失败', error.message);
  }
};

/**
 * 删除评论
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const deleteComment = async (req, res) => {
  try {
    const { id, userId, roleType } = req.query;

    // 查找评论
    const comment = await QuestionComment.findByPk(id);
    if (!comment) {
      return sendResponse(res, 500, '评论不存在');
    }

    // 验证操作权限（只有评论作者或管理员可以删除）
    if (comment.user_id !== userId && roleType !== '0') {
      return sendResponse(res, 500, '无权删除此评论');
    }

    // 使用事务进行删除
    const transaction = await sequelize.transaction();

    try {
      // 删除关联的点赞记录
      await CommentLike.destroy({
        where: { comment_id: id },
        transaction
      });

      // 保存评论的题目ID，用于更新评分
      const questionId = comment.question_id;
      const hasDifficultyRating = !!comment.difficulty_rating;
      const hasQualityRating = !!comment.quality_rating;

      // 直接删除评论（硬删除）
      await comment.destroy({ transaction });

      // 更新题目的平均评分
      if (hasDifficultyRating || hasQualityRating) {
        await updateQuestionAverageRatings(questionId, transaction);
      }

      await transaction.commit();
      sendResponse(res, 200, '评论删除成功');
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  } catch (error) {
    console.error('删除评论失败:', error);
    sendResponse(res, 500, '删除评论失败', error.message);
  }
};

/**
 * 获取用户的所有评论
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getUserComments = async (req, res) => {
  try {
    const { userId, page = 1, pageSize = 10 } = req.query;

    // 计算偏移量
    const offset = (parseInt(page) - 1) * parseInt(pageSize);

    // 查询用户的评论
    const { count, rows } = await QuestionComment.findAndCountAll({
      where: {
        user_id: userId
      },
      include: [
        {
          model: Question,
          as: 'question',
          attributes: ['id', 'content']
        }
      ],
      order: [['create_time', 'DESC']],
      limit: parseInt(pageSize),
      offset: parseInt(offset)
    });

    // 格式化评论数据
    const formattedComments = rows.map(comment => {
      const commentData = comment.toJSON();

      return formatObject({
        id: commentData.id,
        content: commentData.content,
        difficultyRating: commentData.difficulty_rating,
        qualityRating: commentData.quality_rating,
        likes: commentData.likes,
        createTime: commentData.create_time,
        question: {
          id: commentData.question.id,
          content: commentData.question.content
        }
      });
    });

    // 返回评论列表
    sendListResponse(res, 200, '获取用户评论成功', formattedComments, count);
  } catch (error) {
    console.error('获取用户评论失败:', error);
    sendResponse(res, 500, '获取用户评论失败', error.message);
  }
};

/**
 * 获取题目的评分统计
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getQuestionRatings = async (req, res) => {
  try {
    const { questionId } = req.params;

    // 参数验证
    if (!questionId) {
      return sendResponse(res, 500, '参数错误: 题目ID不能为空');
    }

    // 获取题目
    const question = await Question.findByPk(questionId);
    if (!question) {
      return sendResponse(res, 500, '题目不存在');
    }

    // 获取题目的所有评分信息
    const ratingStats = await QuestionComment.findAll({
      attributes: [
        [sequelize.fn('AVG', sequelize.col('difficulty_rating')), 'avgDifficulty'],
        [sequelize.fn('AVG', sequelize.col('quality_rating')), 'avgQuality'],
        [sequelize.fn('COUNT', sequelize.col('id')), 'totalRatings']
      ],
      where: {
        question_id: questionId,
        [Op.or]: [
          { difficulty_rating: { [Op.ne]: null } },
          { quality_rating: { [Op.ne]: null } }
        ]
      }
    });

    // 获取难度评分分布
    const difficultyDistribution = await QuestionComment.findAll({
      attributes: [
        'difficulty_rating',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count']
      ],
      where: {
        question_id: questionId,
        difficulty_rating: { [Op.ne]: null }
      },
      group: ['difficulty_rating'],
      order: [['difficulty_rating', 'ASC']]
    });

    // 获取质量评分分布
    const qualityDistribution = await QuestionComment.findAll({
      attributes: [
        'quality_rating',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count']
      ],
      where: {
        question_id: questionId,
        quality_rating: { [Op.ne]: null }
      },
      group: ['quality_rating'],
      order: [['quality_rating', 'ASC']]
    });

    // 计算平均分和总评分数
    const avgDifficulty = parseFloat(ratingStats[0]?.getDataValue('avgDifficulty')) || 0;
    const avgQuality = parseFloat(ratingStats[0]?.getDataValue('avgQuality')) || 0;
    const totalRatings = parseInt(ratingStats[0]?.getDataValue('totalRatings')) || 0;

    // 构建1-5的评分分布对象
    const diffDistribution = {};
    const qualDistribution = {};

    for (let i = 1; i <= 5; i++) {
      diffDistribution[i] = 0;
      qualDistribution[i] = 0;
    }

    // 填充实际的分布数据
    difficultyDistribution.forEach(item => {
      const rating = item.difficulty_rating;
      if (rating >= 1 && rating <= 5) {
        diffDistribution[rating] = parseInt(item.getDataValue('count'));
      }
    });

    qualityDistribution.forEach(item => {
      const rating = item.quality_rating;
      if (rating >= 1 && rating <= 5) {
        qualDistribution[rating] = parseInt(item.getDataValue('count'));
      }
    });

    // 返回结果
    return sendResponse(res, 200, "获取题目评分统计成功", formatObject({
      questionId,
      averageDifficulty: parseFloat(avgDifficulty.toFixed(1)),
      averageQuality: parseFloat(avgQuality.toFixed(1)),
      ratingCount: totalRatings,
      difficultyDistribution: diffDistribution,
      qualityDistribution: qualDistribution
    }))
  } catch (error) {
    console.error('获取题目评分统计失败:', error);
    sendResponse(res, 500, '获取题目评分统计失败', error.message);
  }
};

/**
 * 更新题目的平均评分
 * @param {string} questionId - 题目ID
 * @param {Object} transaction - 事务对象
 */
const updateQuestionAverageRatings = async (questionId, transaction) => {
  try {
    // 查询所有对该题目的评分
    const ratings = await QuestionComment.findAll({
      attributes: [
        [sequelize.fn('AVG', sequelize.col('difficulty_rating')), 'avgDifficulty'],
        [sequelize.fn('AVG', sequelize.col('quality_rating')), 'avgQuality'],
        [sequelize.fn('COUNT', sequelize.col('id')), 'count']
      ],
      where: {
        question_id: questionId,
        [Op.or]: [
          { difficulty_rating: { [Op.ne]: null } },
          { quality_rating: { [Op.ne]: null } }
        ]
      },
      transaction
    });

    // 检查是否有评分
    const hasRatings = ratings && ratings[0] &&
      (ratings[0].getDataValue('count') > 0);

    // 更新题目的平均评分
    if (hasRatings) {
      // 获取平均值并格式化为一位小数
      const avgDifficulty = parseFloat(ratings[0].getDataValue('avgDifficulty')) || 0;
      const avgQuality = parseFloat(ratings[0].getDataValue('avgQuality')) || 0;
      const count = parseInt(ratings[0].getDataValue('count')) || 0;

      await Question.update({
        user_rated_difficulty: avgDifficulty.toFixed(1),
        user_rated_quality: avgQuality.toFixed(1),
        rating_count: count
      }, {
        where: { id: questionId },
        transaction
      });
    } else {
      // 如果没有评分，则重置所有评分数据为0
      await Question.update({
        user_rated_difficulty: 0,
        user_rated_quality: 0,
        rating_count: 0
      }, {
        where: { id: questionId },
        transaction
      });
    }
  } catch (error) {
    console.error('更新题目平均评分失败:', error);
    throw error;
  }
};

module.exports = {
  addQuestionComment,
  getQuestionComments,
  likeComment,
  deleteComment,
  updateComment,
  getUserComments,
  getQuestionRatings
}; 